package com.edu.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.edu.service.FileService;
import com.edu.util.IOHelper;
import com.edu.vo.FileMeta;


@Controller
@RequestMapping("/files")
public class FileUploadController {

    private LinkedList<FileMeta> files = new LinkedList<FileMeta>();
    private FileMeta fileMeta = null;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private FileService fileService;

    @Value("${prop.upload}")
    private String upload;


    @RequestMapping(value = "jqueryFileUploadDemo", method = RequestMethod.GET)
    public String index() {
        return "upload";
    }


    /***************************************************
     * URL: /files/upload upload(): receives files
     *
     * @param request
     *            : MultipartHttpServletRequest auto passed
     * @param response
     *            : HttpServletResponse auto passed
     * @return LinkedList<FileMeta> as json format
     ****************************************************/
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public @ResponseBody
    LinkedList<FileMeta> upload(MultipartHttpServletRequest request,
                                HttpServletResponse response) {

        // 1. build an iterator
        Iterator<String> itr = request.getFileNames();
        MultipartFile mpf = null;

        // 2. get each file
        while (itr.hasNext()) {

            // 2.1 get next MultipartFile
            mpf = request.getFile(itr.next());
            logger.debug(mpf.getOriginalFilename() + " uploaded! " + files.size());

            // 2.2 if files > 10 remove the first from the list
            if (files.size() >= 10)
                files.pop();

            // 2.3 create new fileMeta
            fileMeta = new FileMeta();
            fileMeta.setFileName(mpf.getOriginalFilename());
            fileMeta.setFileSize(mpf.getSize() / 1024 + " Kb");
            fileMeta.setFileType(mpf.getContentType());

            try {
                fileMeta.setBytes(mpf.getBytes());

                // copy file to local disk (make sure the path "e.g. D:/temp/files" exists)
                FileCopyUtils.copy(mpf.getBytes(), new FileOutputStream(upload + File.separator + mpf.getOriginalFilename()));

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // 2.4 add to files
            files.add(fileMeta);
        }
        // result will be like this
        // [{"fileName":"app_engine-85x77.png","fileSize":"8
        // Kb","fileType":"image/png"},...]
        return files;
    }

    /***************************************************
     * URL:
     *
     * @param response
     *            : passed by the server
     * @param name
     *            : value from the URL
     * @return void
     ****************************************************/
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public void download(HttpServletResponse response, @RequestParam(value = "name") String name) {

        File file = fileService.getFileByName(name);
        ServletOutputStream outputStream = null;
        try {
            byte[] fileBytes = IOHelper.fileToBytes(file);
            logger.debug(fileBytes.toString());
            response.setContentType("application/octet-stream");
            response.setHeader("Content-disposition", "attachment; filename=\"" + file.getName() + "\"");
            response.addHeader("Content-Length", "" + file.length());
            outputStream = response.getOutputStream();
            outputStream.write(fileBytes);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
            logger.debug(e.getMessage());
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
